"""
告警数据处理器

处理IoT设备的告警信息，包括SOS求救信号、设备脱落等紧急情况
"""

from typing import Dict, Any, Optional

from .base_handler import BaseHandler
from dao.es_dao.card_dao import update_card_wearing
from model.wristband_models import WarningData
from utils.wechat_message_util import alert_data


class WarningHandler(BaseHandler):
    """告警数据处理器"""
    
    # 告警类型常量
    WARNING_TYPES = {
        'SOS': 2,           # SOS求救信号
        'DEVICE_OFF': 13    # 设备脱落
    }
    
    def __init__(self):
        super().__init__()
    
    async def handle(self, device_id: str, data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
        """
        处理告警数据
        
        Args:
            device_id: 设备ID
            data: 告警数据字典
            
        Returns:
            处理结果
        """
        try:
            # 将字典数据转换为WarningData模型
            warning = WarningData(**data)
            await self._process_warning_data(warning)
            return {"status": "success", "device_id": device_id, "warning_type": warning.type}
            
        except Exception as e:
            self.log_error(device_id, "告警", e)
            return None
    
    async def _process_warning_data(self, warning: WarningData) -> None:
        """
        处理告警数据的核心逻辑
        
        业务流程：
        1. 根据告警类型分发处理
        2. SOS告警：发送紧急求救通知
        3. 设备脱落告警：更新佩戴状态
        
        Args:
            warning: 告警数据模型
        """
        warning_type = int(warning.type)
        
        if warning_type == self.WARNING_TYPES['SOS']:
            # 处理SOS求救信号
            await self._handle_sos_alert(warning)
            
        elif warning_type == self.WARNING_TYPES['DEVICE_OFF']:
            # 处理设备脱落告警
            await self._handle_device_off_alert(warning)
            
        else:
            # 未知告警类型
            self.logger.warning(f"未知告警类型: {warning_type}, 设备: {warning.device_id}")
    
    async def _handle_sos_alert(self, warning: WarningData) -> None:
        """
        处理SOS求救告警
        
        Args:
            warning: 告警数据模型
        """
        try:
            self.logger.critical(f"收到SOS求救信号: 设备ID={warning.device_id}")
            
            # 发送SOS告警通知
            await alert_data(warning, '发起了SOS求救')
            
            self.logger.info(f"SOS告警处理完成: 设备ID={warning.device_id}")
            
        except Exception as e:
            self.logger.error(f"处理SOS告警失败: {warning.device_id}, 错误: {e}")
    
    async def _handle_device_off_alert(self, warning: WarningData) -> None:
        """
        处理设备脱落告警
        
        Args:
            warning: 告警数据模型
        """
        try:
            self.logger.warning(f"检测到设备脱落: 设备ID={warning.device_id}")
            
            # 获取设备卡片信息
            card = await self.get_device_card(warning.device_id)
            if not card:
                self.logger.error(f"设备脱落告警处理失败，未找到设备卡片: {warning.device_id}")
                return
            
            # 更新设备佩戴状态为false
            await update_card_wearing(False, card.es_id)
            
            self.logger.info(f"设备脱落告警处理完成: 设备ID={warning.device_id}")
            
        except Exception as e:
            self.logger.error(f"处理设备脱落告警失败: {warning.device_id}, 错误: {e}")
    
    def _get_warning_type_description(self, warning_type: int) -> str:
        """
        获取告警类型描述
        
        Args:
            warning_type: 告警类型代码
            
        Returns:
            告警类型描述
        """
        type_descriptions = {
            self.WARNING_TYPES['SOS']: 'SOS求救信号',
            self.WARNING_TYPES['DEVICE_OFF']: '设备脱落告警'
        }
        
        return type_descriptions.get(warning_type, f'未知告警类型({warning_type})')
    
    async def get_warning_statistics(self, device_id: str, start_time: int, end_time: int) -> Dict[str, int]:
        """
        获取设备告警统计信息
        
        Args:
            device_id: 设备ID
            start_time: 开始时间戳
            end_time: 结束时间戳
            
        Returns:
            告警统计字典
        """
        # TODO: 实现告警统计逻辑，可以从数据库查询相关统计信息
        return {
            'sos_count': 0,
            'device_off_count': 0,
            'total_warnings': 0
        }